<script setup lang="ts">
import { h, reactive, ref, useId } from 'vue';

import { CodeEditor } from '@vben/components';

import { WAction } from '@lowcode/components';
import { NButton } from 'naive-ui';

const emit = defineEmits<Emits>();
const code = defineModel<string>('code', {
  default: '',
});
interface Emits {
  (e: 'change', code: string): void;
}
const pattern = ref('');
const showIrrelevantNodes = ref(false);
const context = reactive({
  $state: {
    test: {
      code: '1234',
      msg: '测试的数据',
    },
    aaa: '1234567890',
    userInfo: {
      username: '姓名',
      age: 123_456,
      password: '密码',
      isMember: true,
      userInfo: {
        username: '姓名',
        age: 123_456,
        password: '密码',
        isMember: true,
        userInfo: {
          username: '姓名',
          age: 123_456,
          password: '密码',
          isMember: true,
          userInfo: {
            username: '姓名',
            age: 123_456,
            password: '密码',
            isMember: true,
          },
        },
      },
    },
  },
  $events: {
    onClick() {
      console.log(this);
    },
    onTest() {
      console.log(this);
    },
  },
  onClick() {
    console.log(this);
  },
  onTest() {
    console.log(this);
  },
});
const baseId = useId();
const btnTypes = {
  string: 'default',
  number: 'success',
  boolean: 'error',
  object: 'warning',
  function: 'info',
  array: 'primary',
};
const setData = (objects: Record<string, any> = {}, prefix?: string) => {
  return Object.keys(objects).map((key: string, index: number) => {
    const keys: string[] = [];
    if (prefix) {
      keys.push(prefix);
    }
    keys.push(key);
    const type = Array.isArray(objects[key]) ? 'array' : typeof objects[key];

    const btnType = btnTypes[type] || 'default';
    const item: Record<string, any> = {
      label: key,
      key: keys.join('.'),
      suffix: () => {
        return h(NButton, { size: 'small', type: btnType, text: true }, { default: () => type });
      },
    };
    if (objects[key] && type === 'object') {
      item.children = setData(objects[key], keys.join('.'));
    }
    return item;
  });
};

const data = ref(setData(context));

const selectedKeys = ref([]);
const onConfirm = ({ done }) => {
  if (selectedKeys.value.length > 0) {
    code.value = `this.${selectedKeys.value[0]}`;
    emit('change', code.value);
    done(true);
  } else {
    done(false);
  }
};
</script>

<template>
  <WAction :modal-props="{ class: 'w-[900px] h-[80vh]' }" icon="icon-[mdi--code]" title="JS绑定" tooltip="JS绑定" type="modal" @confirm="onConfirm">
    <n-layout has-sider position="absolute">
      <n-layout-sider :width="380" bordered class="h-full" collapse-mode="width" content-class="px-2">
        <n-tree v-model:selected-keys="selectedKeys" :data="data" :pattern="pattern" :show-irrelevant-nodes="showIrrelevantNodes" block-line check-strategy="child" show-line />
      </n-layout-sider>
      <n-layout-content content-class="px-2">
        <CodeEditor v-model="code" language="js" />
      </n-layout-content>
    </n-layout>
  </WAction>
</template>

<style scoped></style>
